/* eslint-disable no-unused-vars */
import React, { memo, useState, useEffect, useRef, useCallback } from "react";
import { useSelector, useDispatch, shallowEqual } from "react-redux";
import debounce from "lodash/debounce";
import { Search, Popup, Icon } from "@antmjs/vantui";
import { View, Image, Text, Swiper, SwiperItem, ScrollView } from "@tarojs/components";
import Taro, {
  useReady,
  useDidShow,
  useDidHide,
} from "@tarojs/taro";
import WaterfallList from "@/components/WaterfallList";
import Authorization from "@/components/Authorization";
import BasketNav from "@/components/BasketNav"
import BackTop from "@/components/BackTop";
import Navbar from "@/components/Navbar"
import { updateState } from "@/store/actions/global";
import axios from "@/axios";
import {
  getRecipeBanner,
  getRecipeList
} from "@/axios/api/recipe";
import { checkToken } from "@/axios/api/user"
import { themeColor, imgUrl, qiNiuImage } from "@/utils/config";
import "./index.less";


const Index = () => {
  const { globalData } = useSelector(
    (state) => ({ globalData: state.globalData }),
    shallowEqual
  );
  const { isLogin, showBackTop, navbarHeight, systemInfo } = globalData;
  const { screenHeight } = systemInfo
  const [windowHeight] = useState(Taro.getSystemInfoSync().windowHeight);
  const [ScrollViewHeight] = useState(windowHeight - navbarHeight);
  const dispatch = useDispatch();
  const [banner, setBanner] = useState([]);
  const [navList] = useState([
    {
      id: 0,
      image: imgUrl + `icon_random.png`,
      text: "每日推荐",
    },
    {
      id: 1,
      image: imgUrl + `icon_kitchen.png`,
      text: "菜谱分类",
    },
    {
      id: 2,
      image: imgUrl + `icon_fire.png`,
      text: "热门菜谱",
    },
  ])
  const [listLeft, setListLeft] = useState([]);
  const [listRight, setListRight] = useState([]);
  const [isFlowing, setIsFlowing] = useState(false);
  const [refresh, setRefresh] = useState(false);
  const [scrollTop, setScrollTop] = useState(0);
  const [showCard, setShowCard] = useState(false);
  const [flip, setFlip] = useState(false);
  const [cardData, setCard] = useState({});
  const [showIndex, setShow] = useState(true)
  const [bgm] = useState(Taro.createInnerAudioContext());
  const flipRef = useRef();
  const isShaking = useRef();
  const isShow = useRef();
  const waterDom = useRef();
  const handleClickTab = useCallback(
    debounce((type, id) => {
      console.log('CLICK', type, id);
      let url = "";
      if (type === 'recipe') {
        url = '/pages/recipeInfo/index?recipe_id=' + id
      }
      if (type === 'nav') {
        switch (id) {
          case 0:
            // setScrollTop(waterDom.current.top - navbarHeight - Math.random() - 20);
            setShowCard(true);
            return;
            break;
          case 1:
            Taro.switchTab({
              url: '/pages/category/index'
            })
            return;
            break;
          case 2:
            url = '/pages/recipeRank/index';
            break;
        }
      }
      if (!isLogin) {
        dispatch(updateState({
          isShowGrant: true
        }))
      } else {
        jumpTo(url)
      }
    },
      500,
      {
        leading: true,
        trailing: false,
      }
    ), [isLogin]);
  const handleSearch = ({ detail }) => {
    const url = `/pages/recipeSearch/index?cat=${detail}`;
    jumpTo(url);
  }
  const jumpTo = (url) => {
    Taro.navigateTo({
      url
    })
  }
  const checkLoginStatus = () => {
    axios.post(checkToken).then(res => {
      console.log(res);
    })
  }
  const showRecipeItem = async (list) => {
    for (let i = 0; i < list.length; i++) {
      const item = list[i];
      const { leftHeight, rightHeight } = await getListHeight();
      const { w, h } = item.size;
      const cats = item.category.split(',').sort(() => {
        return 0.5 - Math.random();
      });
      item.cats = cats;
      let itemHeight = h / w * ((waterDom.current.width) * 0.48);
      item.height = itemHeight;
      if (!isShow.current) {
        return
      }
      if (leftHeight <= rightHeight) {
        setListLeft((preList) => [...preList, item])
      } else {
        setListRight((preList) => [...preList, item]);
      }
      if (i === list.length - 1) {
        setIsFlowing(false);
      }
    }
  };
  const handleShake = () => {
    if (!isShaking.current) {
      Taro.vibrateLong().then(() => {
        setFlip(false);
        isShaking.current = true;
        let hobby = Taro.getStorageSync('hobby');
        let cat = hobby[Math.floor(Math.random() * hobby.length)];
        axios.get(getRecipeList, { params: { cat, num: 1 } }).then((res) => {
          const { data, code } = res;
          if (code === 200) {
            console.log('random', flip, cat, data.list);
            let time = 0;
            if (flipRef.current) {
              time = 1000;
            }
            flipRef.current = false;
            setTimeout(() => {
              setCard(data.list[0]);
              setFlip(true);
              flipRef.current = true;
              bgm.stop();
              bgm.play();
            }, time);
          }
        })
        setTimeout(() => {
          isShaking.current = false;
        }, 2000);
      })
    }
  };
  const getList = (page = 0, delay) => {
    if (isFlowing && page !== 1) {
      return
    }
    setIsFlowing(true);
    let hobby = Taro.getStorageSync('hobby');
    let cat = hobby[Math.floor(Math.random() * hobby.length)];
    axios.get(getRecipeList, { params: { cat } }).then((res) => {
      const { data, code } = res;
      if (code === 200) {
        if (page) {
          setListLeft([]);
          setListRight([]);
        }
        if (delay) {
          setTimeout(() => {
            showRecipeItem(data.list)
          }, delay);
        } else {
          showRecipeItem(data.list)
        }
      }
    });
  };
  const getBanner = () => {
    axios.get(getRecipeBanner).then((res) => {
      const { data, code } = res;
      if (code === 200) {
        setBanner(data.list);
      }
    });
  };
  const getListHeight = () => {
    return new Promise(resovle => {
      const query = Taro.createSelectorQuery();
      setTimeout(() => {
        query.selectAll('.list').boundingClientRect(rec => {
          const leftHeight = rec[0] ? rec[0].height : 0;
          const rightHeight = rec[1] ? rec[1].height : 0;
          resovle({ leftHeight, rightHeight })
        }).exec()
      }, 0)
    })
  }
  const init = () => {
    const query = Taro.createSelectorQuery();
    query.select('.scroll').boundingClientRect(rec => {
      if (rec) {
        const { width, top } = rec;
        waterDom.current = {
          width,
          top: top
        }
        getList(1);
      } else {
        init();
      }
    }).exec()
  }
  const PullDownRefresh = (() => {
    setRefresh(true)
    getBanner();
    getList(1);
    setTimeout(() => {
      setRefresh(false)
    }, 700);
  })
  const PageScroll = ({ detail }) => {
    const flag = detail.scrollTop > windowHeight * 1.5;
    if (flag !== showBackTop) {
      dispatch(updateState({
        showBackTop: flag
      }))
    }
  }
  const ReachBottom = (() => {
    if (listLeft.length + listRight.length < 80) {
      getList();
    } else {
      setScrollTop(waterDom.current.top - navbarHeight - Math.random() - 20);
      setListLeft([]);
      setListRight([]);
      getList(1, 600)
    }
  });
  useEffect(() => {
    getBanner();
    bgm.src = imgUrl + 'bgm.mp3';
    if (!isLogin) {
      dispatch(updateState({
        isShowGrant: true
      }))
    } else {
      checkLoginStatus();
    }
  }, [dispatch, isLogin]);
  useEffect(() => {
    if (showCard && showIndex) {
      // 监听摇一摇 加速度数据
      Taro.onAccelerometerChange((res) => {
        if (res.x > 1 || res.y > 1 || res.z > 1) {
          handleShake();
        }
      });
    } else {
      Taro.offAccelerometerChange();
      bgm.stop();
    }
  }, [showCard, showIndex]);
  useEffect(() => {
    if (showCard) {
      setFlip(false);
      flipRef.current = false;
    }
  }, [showCard])
  useDidShow(() => {
    if (isFlowing) {
      setIsFlowing(false);
    }
    if (listLeft.length < 3 && listRight.length < 3 && waterDom.current) {
      getList(1);
    }
    isShow.current = true;
    setShow(true)
  });
  useReady(() => {
    init();
  })
  useDidHide(() => {
    isShow.current = false;
    setShow(false);
  });




  return (
    <View className='index'>
      <Navbar title='就离谱鹅' ></Navbar>
      <ScrollView
        className='scroll'
        scrollTop={scrollTop}
        scrollWithAnimation
        style={{ height: ScrollViewHeight }}
        scroll-y
        refresherEnabled
        onScroll={PageScroll}
        onRefresherRefresh={PullDownRefresh}
        onScrollToLower={ReachBottom}
        refresherTriggered={refresh}
        scrollAnchoring
        enhanced
      >
        <View className='search'>
          <Search
            value=''
            onSearch={(e) => handleSearch(e)}
            shape='round'
            maxlength='15'
            background='transparent'
            placeholder='今天想吃什么'
          />
        </View>
        <View className='banner'>
          <Swiper
            className='banner-swiper'
            indicatorColor='rgba(0,0,0,.2)'
            indicatorActiveColor={themeColor}
            circular
            indicatorDots
            autoplay
            interval='3000'
          >
            {banner.map((item, index) => {
              return (
                <SwiperItem key={item.recipe_id}>
                  <View className={"swiper-item swipe-item-" + index} onClick={() => { handleClickTab('recipe', item.recipe_id) }}>
                    <Image src={item.image} mode='aspectFill' />
                  </View>
                </SwiperItem>
              );
            })}
          </Swiper>
        </View>
        <View className='nav'>
          {navList.map((item) => {
            return (
              <View className='nav-item' key={item.id} onClick={() => handleClickTab('nav', item.id)}>
                <Image src={item.image} />
                <Text className='nav-item-text'>{item.text}</Text>
              </View>
            );
          })}
        </View>
        <WaterfallList listLeft={listLeft} listRight={listRight} handleClickTab={handleClickTab} isFlowing={isFlowing}></WaterfallList>

      </ScrollView>
      <View>
        <BasketNav top={.75 * screenHeight} />
      </View>
      <View>
        {showBackTop ? <BackTop onClick={() => {
          dispatch(updateState({
            showBackTop: false
          }))
          setScrollTop(Math.random())
        }} top={.75 * screenHeight}
        /> : null}
      </View>
      {/* 这种写法会有bug，taro对于楼层节点的更新有缺陷
        {showBackTop ? <BackTop onClick={() => {
          dispatch(updateState({
            showBackTop: false
          }))
          setScrollTop(Math.random())
        }} top={.75 * screenHeight}
        /> : null}
      */}
      <View><Authorization></Authorization></View>
      <Popup show={showCard} onClose={() => {
        setShowCard(false);
      }} style={{
        background: 'transparent',
        padding: '50px 20px'
      }}
      >
        <View class={`'flip-box' ${flip && 'flip'}`} >
          <View class='flip-item flip-item-front'>
            <View className='penguin'>
              <Image src={imgUrl + 'logo.png'} mode='widthFix' />
            </View>
          </View>
          <View class='flip-item flip-item-back'>
            <View className='random-img' onClick={() => handleClickTab('recipe', cardData.recipe_id)}>
              <Image src={cardData.image} mode='aspectFill'></Image>
              <View className='title'>
                <View className='ibl'>
                  <Text>{cardData.title}</Text>
                </View>
              </View>
            </View>
          </View>
        </View>
        <View className='btn-shake' onClick={handleShake}><Text>摇一摇</Text><Image src={qiNiuImage + 'public/shake_icon.png'}></Image></View>
        <View className='pop-close'>
          <Icon name='close' size='65' color='#dddddd' onClick={() => {
            setShowCard(false);
          }}
          ></Icon>
        </View>
      </Popup>
    </View>
  );
};

export default memo(Index);
